home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer)…68k, x86, SPARC, PA-RISC] / NeXTSTEP 3.3 Dev Intel.iso / NextDeveloper / Examples / DatabaseKit / Evaluator / SQLWindow.m < prev   
Encoding:
Text File  |  1993-07-21  |  3.9 KB  |  153 lines

  1. /* SQLWindow.m:
  2.  * You may freely copy, distribute, and reuse the code in this example.
  3.  * NeXT disclaims any warranty of any kind, expressed or  implied, as to its
  4.  * fitness for any particular use.
  5.  *
  6.  * Written by Jack Greenfield
  7.  *
  8.  */
  9.  
  10. #import    "ScrollViewExtras.h"
  11. #import "SQLWindow.h"
  12. #import    "MultiBinder.h"
  13.  
  14. #define FAILURE NXLocalizedString("Failure:", NULL, \
  15.     "Message given to user when an operation has failed.")
  16.  
  17. #define CANNOT_CONNECT NXLocalizedString("Cannot connect to database", NULL, \
  18.     "Message given to user to explain what fails. ")
  19.  
  20. #define OK NXLocalizedString("OK", NULL, "Okay to continue ")
  21.  
  22. @implementation SQLWindow
  23.  
  24. - free
  25. {
  26.     [database free];
  27.     return [super free];
  28. }
  29.  
  30. - initWithFile:(const char *)filename
  31. {
  32.     char path[MAXPATHLEN];
  33.  
  34.     if ((self = [super init]) != nil)
  35.     {
  36.     database = [[DBDatabase alloc] initFromFile:filename];
  37.     if (![database connect])
  38.     {
  39.         NXRunAlertPanel(FAILURE, CANNOT_CONNECT, OK, NULL, NULL);
  40.         return [self free];
  41.     }
  42.  
  43.     [[NXBundle mainBundle] getPath:path forResource:"SQLWindow" ofType:"nib"];
  44.     [NXApp loadNibFile:path owner:self withNames:NO];
  45.     [[resultsView window] setDelegate:self];
  46.     [[resultsView window] setTitleAsFilename:filename];
  47.     [[queryView docView] selectAll:self];
  48.     [[resultsView window] makeKeyAndOrderFront:self];
  49.     }
  50.  
  51.     return self;
  52. }
  53.  
  54. - database { return database; }
  55.  
  56. - evaluate:sender
  57. {
  58.     int    charCount;
  59.     char *buffer;
  60.     MultiBinder *binder;
  61.     id <DBContainers> rowsList;
  62.     
  63.     if ((charCount = [[queryView docView] textLength]) > 0)
  64.     {
  65.     binder = [[MultiBinder alloc] initFromPropertyLists:nil];
  66.     [binder setDatabase:database];
  67.     [binder setDelegate:self];
  68.     rowsList = [[List alloc] init];
  69.     [binder setContainer: rowsList];
  70.  
  71.     buffer = (char *) alloca(1 + charCount);
  72.     [[queryView docView] getSubstring:buffer start:0 length:charCount];
  73.     buffer[charCount] = 0;
  74.     while (charCount > 0 && buffer[--charCount] == '\n')
  75.         buffer[charCount] = 0;
  76.  
  77.     [resultsView sprintf:"%s\n", buffer];
  78.     if (![binder evaluateString:buffer])
  79.         [resultsView sprintf:"EVALUATION FAILED\n\n"];
  80.     else
  81.     if (![binder fetch])
  82.         [resultsView sprintf:"FETCH FAILED\n\n"];
  83.     else
  84.             /* For the last result set, binderWillChangeResultSet
  85.              * needs to be called explicitly.
  86.              */
  87.         [self binderWillChangeResultSet:binder];
  88.     
  89.     [resultsView sprintf:"\n"];
  90.     [binder free];
  91.     [(List *)rowsList free];
  92.     }
  93.  
  94.     [[queryView docView] selectText:self];
  95.     return self;
  96. }
  97.  
  98. - clear:sender
  99. {
  100.     [resultsView clear:sender];
  101.     [[queryView docView] selectText:self];
  102.     return self;
  103. }
  104.  
  105. - print:sender
  106. {
  107.     [resultsView print:sender];
  108.     [[queryView docView] selectText:self];
  109.     return self;
  110. }
  111.  
  112. /* This delegate method will be called every time a new result set is being
  113.  * fetched. All objects returned by the binder fetch can be retrieved from the 
  114.  * binder container (named rowsList here). Note that the container will get
  115.  * flushed everytime a new result set is retrieved. This delegate method is the
  116.  * place where you can save the result set elsewhere if needed.
  117.  */
  118. - binderWillChangeResultSet:(MultiBinder *)binder
  119. {
  120.     int rowsIndex;
  121.     int rowsCount;
  122.     int propIndex;
  123.     int propCount;
  124.     List *rowsList;
  125.     List *propList;
  126.     
  127.     propList = [[List alloc] init];
  128.     [binder getCurrentProperties:propList];
  129.     rowsList = binder->container; // public instance variable!!!
  130.     rowsCount = [rowsList count];
  131.     [resultsView sprintf:"\nresult set %d\n", [binder currentResultSet]];
  132.     [resultsView sprintf:"%u records selected\n", rowsCount];
  133.     [binder setFirst];
  134.     for (rowsIndex = 0; rowsIndex < rowsCount; ++rowsIndex)
  135.     {
  136.     propCount = [propList count];
  137.     for (propIndex = 0; propIndex < propCount; ++propIndex)
  138.     {
  139.         id p = [propList objectAt:propIndex];
  140.         [resultsView sprintf:"%s=(%s) ", 
  141.         [p name], [[binder valueForProperty:p] stringValue]];
  142.     }
  143.  
  144.     [resultsView sprintf:"\n"];
  145.     [binder setNext];
  146.     }
  147.  
  148.     [propList free];
  149.     return self;
  150. }
  151.  
  152. @end
  153.